//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2002-2006
//
// Change properties defined in the map header.
//

# include "StdAfx.h"
# include "ChangeMapHeader.h"
# include "UndoRedo.h"

class CChangeMapHeaderAction : public CEditAction {
  public:
	CChangeMapHeaderAction (const map_header_t & _Header) :
		m_HeaderOld (g_map.Header),
		m_Header (_Header)
	{}

	virtual void GetName (string_t & _str) const {
		_str.append ("Change map header");
	}
	virtual cu_t CanUndo () const {return cuYes;}
	virtual bool Do ();
	virtual void Undo ();
	virtual void Redo () {CChangeMapHeaderAction::Do ();}

  private:
	map_header_t const m_HeaderOld;
	map_header_t const m_Header;
};

bool CChangeMapHeaderAction::Do () {
	CCritSec::CLock lock (g_cs);

	g_map.Header = m_Header;

	return true;
}

void CChangeMapHeaderAction::Undo () {
	CCritSec::CLock lock (g_cs);

	g_map.Header = m_HeaderOld;
}

////////////////////////////////////////////

class CEditMHExtraAction : public CEditAction {
  public:
	CEditMHExtraAction (const string_t & _strKey, const string_t & _strValue) :
		m_strKey (_strKey),
		m_strValue (_strValue)
	{}

	virtual void GetName (string_t & _str) const {
		_str.append ("Edit map header");
	}
	virtual cu_t CanUndo () const {return cuYes;}
	virtual bool Do ();
	virtual void Undo ();
	virtual void Redo () {CEditMHExtraAction::Do ();}

  private:
	const string_t m_strKey;
	string_t m_strValue;
};

bool CEditMHExtraAction::Do () {
	CCritSec::CLock lock (g_cs);

	const map_header_t::extra_t::iterator ei = g_map.Header.extra.find (m_strKey);
	if (ei == g_map.Header.extra.end ())
		return false;

	ei->second.swap (m_strValue);

	return true;
}

void CEditMHExtraAction::Undo () {
	CEditMHExtraAction::Do ();
}

////////////////////////////////////////////

class CDeleteMHExtraAction : public CEditAction {
  public:
	CDeleteMHExtraAction (const string_t & _strKey) :
		m_strKey (_strKey)
	{}

	virtual void GetName (string_t & _str) const {
		_str.append ("Edit map header");
	}
	virtual cu_t CanUndo () const {return cuYes;}
	virtual bool Do ();
	virtual void Undo ();
	virtual void Redo () {CDeleteMHExtraAction::Do ();}

  private:
	const string_t m_strKey;
	string_t m_strValue;
};

bool CDeleteMHExtraAction::Do () {
	CCritSec::CLock lock (g_cs);

	const map_header_t::extra_t::iterator ei = g_map.Header.extra.find (m_strKey);
	if (ei == g_map.Header.extra.end ())
		return false;

	ei->second.swap (m_strValue);

	g_map.Header.extra.erase (ei);

	return true;
}

void CDeleteMHExtraAction::Undo () {
	CCritSec::CLock lock (g_cs);

	g_map.Header.extra [m_strKey] = m_strValue;
}

////////////////////////////////////////////

class CAddMHExtraAction : public CEditAction {
  public:
	CAddMHExtraAction (const string_t & _strKey, const string_t & _strValue) :
		m_strKey (_strKey),
		m_strValue (_strValue)
	{}

	virtual void GetName (string_t & _str) const {
		_str.append ("Edit map header");
	}
	virtual cu_t CanUndo () const {return cuYes;}
	virtual bool Do ();
	virtual void Undo ();
	virtual void Redo () {CAddMHExtraAction::Do ();}

  private:
	const string_t m_strKey;
	string_t m_strValue;
};

bool CAddMHExtraAction::Do () {
	CCritSec::CLock lock (g_cs);

	g_map.Header.extra [m_strKey] = m_strValue;

	return true;
}

void CAddMHExtraAction::Undo () {
	CCritSec::CLock lock (g_cs);

	const map_header_t::extra_t::iterator ei = g_map.Header.extra.find (m_strKey);
	if (ei != g_map.Header.extra.end ())
		g_map.Header.extra.erase (ei);
}

////////////////////////////////////////////

void ChangeMapHeader (const map_header_t & _Header) {
	PerformEditAction (new CChangeMapHeaderAction (_Header));
}

void EditMapHeaderExtra (const string_t & _strKey, const string_t & _strValue) {
	PerformEditAction (new CEditMHExtraAction (_strKey, _strValue));
}

void DeleteMapHeaderExtra (const string_t & _strKey) {
	PerformEditAction (new CDeleteMHExtraAction (_strKey));
}

void AddMapHeaderExtra (const string_t & _strKey, const string_t & _strValue) {
	PerformEditAction (new CAddMHExtraAction (_strKey, _strValue));
}